<?php
require 'vendor/autoload.php';

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;

class EditorServer implements MessageComponentInterface {
    protected $clients;
    protected $content = '';
    protected $username = 'Guest';

    // 用于存储文件权限和连接的数据结构
    protected $filePermissions = [];

    public function __construct() {
        $this->clients = new \SplObjectStorage;
    }

    // 当新连接建立时调用
    public function onOpen(ConnectionInterface $conn) {
        $this->clients->attach($conn);
        echo "新连接！({$conn->resourceId})\n";

        // 检查并将连接添加到文件权限
        foreach ($this->filePermissions as $file => $connections) {
            if (in_array($this->username, $connections)) {
                $this->filePermissions[$file][] = $conn;
            }
        }

        $conn->send(json_encode([
            'username' => $this->username,
            'content' => $this->content
        ]));
    }

    // 当收到消息时调用
    public function onMessage(ConnectionInterface $from, $msg) {
        $data = json_decode($msg, true);

        if (isset($data['username'])) {
            // ...

        }

        if (isset($data['content']) && isset($data['file'])) {
            $file = $data['file'];
            $content = $data['content'];

            // 修改指定的文件内容
            file_put_contents($file, $content);

            // 通知拥有权限的用户文件已经修改
            foreach ($this->filePermissions[$file] as $connection) {
                $connection->send(json_encode([
                    'event' => 'fileChange',
                    'file' => $file
                ]));
            }

            // ...
        }
    }

    // 当连接关闭时调用
    public function onClose(ConnectionInterface $conn) {
        $this->clients->detach($conn);
        echo "连接 {$conn->resourceId} 已断开\n";

        // 从文件权限中移除连接
        foreach ($this->filePermissions as $file => &$connections) {
            $index = array_search($conn, $connections);
            if ($index !== false) {
                unset($connections[$index]);
            }
        }
    }

    // ...
}

$server = IoServer::factory(
    new HttpServer(
        new WsServer(
            new EditorServer()
        )
    ),
    8080
);

$server->run();
